package com.mobilesales.android;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.*;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.mobilesales.android.actionbar.Main_ActionBar;
import com.mobilesales.android.activities.clients.Clients;
import com.mobilesales.android.activities.common.SettingsActivity;
import com.mobilesales.android.activities.employees.MessageRead;
import com.mobilesales.android.activities.employees.Messages;
import com.mobilesales.android.activities.orders.Orders;
import com.mobilesales.android.activities.products.Products;
import com.mobilesales.android.activities.tasks.DetailsTask;
import com.mobilesales.android.activities.tasks.ListTask;
import com.mobilesales.android.activities.tasks.Tasks;
import com.mobilesales.android.adapters.SlidingMenus;
import com.mobilesales.android.c2dm.C2DMMessaging;
import com.mobilesales.android.c2dm.C2DMReceiver;
import com.mobilesales.android.c2dm.NotificationReceiver;
import com.mobilesales.android.c2dm.parsers.MessageParser;
import com.mobilesales.android.database.EmployeeManager;
import com.mobilesales.android.database.TaskManager;
import com.mobilesales.android.infrastructure.Language;
import com.mobilesales.android.infrastructure.MenuItem;
import com.mobilesales.android.infrastructure.SyncTask;
import com.mobilesales.android.model.employees.Employee;
import com.mobilesales.android.model.employees.EmployeeAccess;
import com.mobilesales.android.model.employees.Message;
import com.mobilesales.android.model.tasks.CyclicTask;
import com.mobilesales.android.model.tasks.Schedule;
import com.mobilesales.android.model.tasks.Task;
import com.mobilesales.android.services.AuthServiceClient;
import com.mobilesales.android.services.Configuration;
import com.mobilesales.android.util.Constants;
import com.mobilesales.android.util.DateUtil;
import com.mobilesales.android.util.LogFlags;
import com.mobilesales.android.util.MessageBox;
import com.mobilesales.android.util.SelectDateTime;
import com.mobilesales.android.util.Settings;
import com.mobilesales.android.util.Settings.UnformatedEndpoints;

public class MobileSalesActivity extends ActionBarActivity {

	// private ArrayAdapter<MenuItem> menuItems;
	private Handler handler = new Handler();
	private ProgressDialog progressDialog;

	private NotificationReceiver notificationReceiver;
	private MessageParser messageParser;

	LinearLayout lay_products;
	LinearLayout lay_clients;
	LinearLayout lay_tasks;
	LinearLayout lay_massages;
	LinearLayout lay_setting;
	LinearLayout lay_order;

	LinearLayout lay_listTaskToDay;
	LinearLayout lay_listTaskParent;
	LinearLayout lay_ListNewMess;
	LinearLayout lay_listMessParent;

	TextView tvToday;

	private List<Task> tasksOfDay;
	private Map<Integer, String> employeeNames;
	private List<Employee> employees;
	private List<Message> listMessages;

	Date dateToDay;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// ((ActionBarActivity)this).getSupportActionBar();
		new Main_ActionBar(this).getActionBar(getSupportActionBar());

		Settings settings = Settings.getSettings();
		this.initLanguage(settings);
		this.initLayoutButton();

		ActionBar actionbar = getSupportActionBar();
		new Main_ActionBar(this).getActionBar(actionbar);
		// MobileSalesActivity.this.buildMenu(settings);

		messageParser = new MessageParser(this);

		if (getIntent().getFlags() == Intent.FLAG_ACTIVITY_NEW_TASK) {
			// syncData();
		}
		if (settings == null) {
			this.startActivityForResult(
					new Intent(this, SettingsActivity.class),
					Constants.RequestCodes.ChangeSettings);
		}
	}

	/**
	 * Init values
	 */
	private void initLayoutButton() {
		lay_products = (LinearLayout) findViewById(R.id.main_products);
		lay_clients = (LinearLayout) findViewById(R.id.main_client);
		lay_massages = (LinearLayout) findViewById(R.id.main_messages);
		lay_order = (LinearLayout) findViewById(R.id.main_orders);
		lay_tasks = (LinearLayout) findViewById(R.id.main_tasks);
		lay_setting = (LinearLayout) findViewById(R.id.main_settings);

		lay_listTaskToDay = (LinearLayout) findViewById(R.id.main_layout_list_task);
		lay_ListNewMess = (LinearLayout) findViewById(R.id.main_layout_list_messages);

		lay_listTaskParent = (LinearLayout) findViewById(R.id.main_layout_taskParent);
		lay_ListNewMess = (LinearLayout) findViewById(R.id.main_layout_messageParent);

		tvToday = (TextView) findViewById(R.id.main_text_today);
		getTaskToDay();
		getNewMessage();
	}

	/**
	 * 
	 */
	private void getTaskToDay() {
		tasksOfDay = new ArrayList<Task>();
		Calendar calendar = Calendar.getInstance();
		dateToDay = calendar.getTime();
		String stoday = new SelectDateTime(this).FormatDate(dateToDay);
		tvToday.setText(stoday);
		if (calendar != null) {
			List<Task> tasks = getTasks(dateToDay);
			List<CyclicTask> cyclicTasks = getCyclicTasks(dateToDay);
			if (tasks != null) {
				for (Task tsk : tasks)
					tasksOfDay.add(tsk);
			}
			if (cyclicTasks != null) {
				for (CyclicTask tsk : cyclicTasks)
					tasksOfDay.add(tsk);
			}
		}
		setTask();
	}

	private void setTask() {
		if (tasksOfDay != null || tasksOfDay.size() != 0) {
			MessageBox.show(this, tasksOfDay.size() + "");
			for (int i = 0; i < tasksOfDay.size() && i < 2; i++) {
				final Task t = tasksOfDay.get(i);
				LinearLayout ll = (LinearLayout) LayoutInflater.from(this)
						.inflate(R.layout.task_list_item, null);

				ll.setBackgroundResource(R.drawable.border_gray_light);

				TextView tasktype = (TextView) ll.findViewById(R.id.taskType);
				TextView taskInfoField = ((TextView) ll
						.findViewById(R.id.taskInfo));
				TextView taskStatusTxt = ((TextView) ll
						.findViewById(R.id.taskStatus));
				TextView taskDateTxt = ((TextView) ll
						.findViewById(R.id.taskTimeSpan));

				String taskInfo = t.Info;
				if (taskInfo == null || taskInfo.equals(""))
					taskInfoField.setVisibility(View.GONE);
				else
					taskInfoField.setText(taskInfo);

				tasktype.setText(t.TaskType.Name);

				taskStatusTxt.setText(String.format("%s: %s",
						this.getString(R.string.Status), t.TaskStatus));

				taskDateTxt.setText(DateUtil.toTimeDistance(t.StartTime,
						t.EndTime));

				ImageView icon = (ImageView) ll.findViewById(R.id.taskIcon);
				icon.setVisibility(View.VISIBLE);
				boolean isCyclicTask = (t instanceof CyclicTask);

				icon.setImageResource(isCyclicTask ? R.drawable.cyclic_task_icon
						: R.drawable.task_icon);

				ll.setOnClickListener(new OnClickListener() {

					public void onClick(View v) {
						// TODO Auto-generated method stub
						Intent intent = new Intent(v.getContext(),
								DetailsTask.class);
						intent.putExtra(Constants.TaskId, t.Id);
						intent.putExtra(Constants.IsCyclicTask,
								t instanceof CyclicTask);
						startActivityForResult(intent, 0);
					}
				});

				lay_listTaskToDay.addView(ll);
			}
		} else
			lay_listTaskToDay.setVisibility(View.GONE);
	}

	/**
	 * 
	 * @param currentDate
	 * @return
	 */
	private List<CyclicTask> getCyclicTasks(Date currentDate) {
		Log.i("currentDate", currentDate.toLocaleString());
		TaskManager manager = new TaskManager(this);
		List<CyclicTask> tasks = manager.GetCyclicTaskList(Settings
				.getSettings().getEmployeeId());
		manager.Close();

		SelectDateTime selectdate = new SelectDateTime(this);
		List<CyclicTask> taskInTime = null;
		if (tasks != null) {
			taskInTime = new ArrayList<CyclicTask>();
			GregorianCalendar calendar = new GregorianCalendar();
			for (CyclicTask tsk : tasks) {
				Date date = selectdate.getDate(tsk.StartTime);
				calendar.setTime(date);
				GregorianCalendar current = new GregorianCalendar();
				current.setTime(currentDate);
				current.set(GregorianCalendar.HOUR_OF_DAY,
						calendar.get(GregorianCalendar.HOUR_OF_DAY));
				current.set(GregorianCalendar.MINUTE,
						calendar.get(GregorianCalendar.MINUTE));

				Log.i("Current", current.getTime().toLocaleString());
				Log.i("Day", calendar.getTime().toLocaleString());

				long diff = current.getTimeInMillis()
						- calendar.getTimeInMillis();
				Log.i("diff", diff + "");
				Log.i("taskInterval", tsk.TaskInterval + "");
				Log.i("diff % tsk.TaskInterval", (diff % tsk.TaskInterval) + "");
				if (diff >= 0) {
					diff /= (24 * 60 * 60 * 1000);
					if (tsk.TaskInterval != 0 && diff % tsk.TaskInterval == 0)
						taskInTime.add(tsk);
				}
			}
			Log.i("MobileSales", "taskInTime:" + taskInTime.size());
		}
		return taskInTime;
	}

	private List<Task> getTasks(Date date) {
		List<Task> tasks = null;
		TaskManager manager = new TaskManager(this);
		List<Schedule> schedules = manager.GetScheduleList(Settings
				.getSettings().getEmployeeId());
		// get all Task
		if (schedules != null) {
			tasks = new ArrayList<Task>();
			for (Schedule s : schedules) {
				List<Task> stasks = manager.GetTaskList(s.Id);
				if (stasks != null) {
					tasks.addAll(stasks);
				} else {
					tasks = null;
					break;
				}
			}
		}
		manager.Close();
		//
		SelectDateTime selectDate = new SelectDateTime(this);
		if (tasks != null) {
			List<Task> incorrect = new ArrayList<Task>();
			for (Task t : tasks) {
				// so sanh 2 ngay
				String currentDate = selectDate.FormatDate(date);
				String taskDate = selectDate.FormatDate(t.StartTime);
				if (!currentDate.equals(taskDate)) {
					incorrect.add(t);
				}
			}
			for (Task t : incorrect)
				tasks.remove(t);
		}
		return tasks;
	}

	/**
	 * 
	 */
	private void getNewMessage() {
		employees = getEmployees();
		if (employees != null) {
			listMessages = getItems();
			if (listMessages != null) {
				setListMessage();
			}
		}

	}

	void setListMessage() {
		if (listMessages != null || listMessages.size() != 0) {
			for (final Message msg : listMessages) {
				if (msg.IsNew) {
					LinearLayout v = (LinearLayout) LayoutInflater.from(this)
							.inflate(R.layout.message_list_item, null);
					TextView contentField = (TextView) v
							.findViewById(R.id.msgSubject);
					TextView senderField = (TextView) v
							.findViewById(R.id.msgSenderTxt);
					TextView dateField = (TextView) v
							.findViewById(R.id.msgDateTxt);
					ImageView icon = (ImageView) v
							.findViewById(R.id.message_adapter_icon);
					contentField.setText(msg.Subject);
					String senderName = this.employeeNames.get(msg.SenderId);
					if (senderName == null)
						senderName = msg.SenderLogin;
					String from = String.format("%s: %s",
							this.getString(R.string.From), senderName);
					senderField.setText(from);

					dateField.setText(DateUtil
							.toMessageDateString(msg.SendDate));
					v.setOnClickListener(new OnClickListener() {

						public void onClick(View view) {
							// TODO Auto-generated method stub
							Intent intent = new Intent(view.getContext(),
									MessageRead.class);
							intent.putExtra(Constants.MessageId, msg.Id);
							startActivityForResult(intent, 0);
						}
					});
					lay_ListNewMess.addView(v);
				}
			}
		} else {
			lay_listMessParent.setVisibility(View.GONE);
		}
	}

	/**
	 * 
	 * @return
	 */
	private List<Employee> getEmployees() {
		EmployeeManager manager = new EmployeeManager(this);
		List<Employee> employees = manager.GetEmployeeList();
		employeeNames = new HashMap<Integer, String>();
		manager.Close();
		for (Employee e : employees) {
			employeeNames.put(e.Id, e.Lastname + " " + e.Firstname);
		}
		return employees;
	}

	/**
	 * 
	 * @return
	 */
	protected List<Message> getItems() {
		EmployeeManager manager = new EmployeeManager(this);
		List<Message> messages = manager.GetMessageList();
		manager.Close();
		return messages;
	}

	/**
	 * 
	 * @param settings
	 */
	private void initLanguage(Settings settings) {
		if (settings != null) {
			String lang = settings.getLanguage();
			if (lang != null && !lang.equals("")) {
				Language.setCurrentLanguage(this, lang);
			}
		}
	}

	private NotificationReceiver createNotificationReceiver() {
		return new NotificationReceiver(handler) {
			@Override
			public void onRegistered(String registrationId) {
				init(registrationId);
			}

			@Override
			public void onMessage(String message) {
				Boolean success = messageParser.parseMessage(message);
				Log.i("refreshing", "success:" + success);
				MessageBox.show(MobileSalesActivity.this,
						getString(R.string.Refreshing));
			}

			@Override
			public void onError(String errorId) {
				Log.e("NotificationReceiver", "onError: " + errorId);
				MessageBox.show(MobileSalesActivity.this,
						MobileSalesActivity.this
								.getString(R.string.ErrorC2DMRegistration));
			}
		};
	}

	private void syncData() {
		if (notificationReceiver == null)
			notificationReceiver = this.createNotificationReceiver();
		C2DMMessaging.addNotificationReceiver(notificationReceiver);

		Settings settings = Settings.getSettings();
		if (settings == null)
			return;

		// if (settings.getC2dmRegistrationId().equals("")) {
		String serverMail = settings.getC2dmServerMail();
		C2DMReceiver.senderId = serverMail;
		// Log.i("C2DM - register", "senderId:"+serverMail);
		C2DMMessaging.register(this, serverMail);
		// }
		// else
		// this.init(settings.getC2dmRegistrationId());
	}

	private void init(final String c2dmRegistrationId) {
		final Settings settings = Settings.getSettings();

		try {
			settings.setC2dmRegistrationId(c2dmRegistrationId);
			settings.save();
		} catch (IOException e1) {
			Log.e("c2dm", e1.getMessage(), e1);
			MessageBox.show(MobileSalesActivity.this,
					MobileSalesActivity.this.getString(R.string.ErrorSave));
			return;
		}

		Thread thread = new Thread() {
			public void run() {
				if (settings != null) {

					handler.post(new Runnable() {
						public void run() {
							progressDialog = ProgressDialog.show(
									MobileSalesActivity.this, null,
									MobileSalesActivity.this
											.getText(R.string.LoggingIn));
						}
					});
					EmployeeAccess access = MobileSalesActivity.this.login(
							settings.getServerUrl(), settings.getLogin(),
							settings.getPassword(), c2dmRegistrationId);
					if (access != null) {

						settings.setC2dmRegistrationId(c2dmRegistrationId);
						settings.setEmployeeId(access.EmployeeId);
						settings.setToken(access.Token);
						try {
							settings.save();
							handler.post(new Runnable() {
								public void run() {
									progressDialog.dismiss();
									MobileSalesActivity.this
											.syncCheck(settings);
								}
							});
						} catch (IOException e) {
							Log.e("Save settings", e.getMessage(), e);
						}
					} else {
						handler.post(new Runnable() {
							public void run() {
								progressDialog.dismiss();
								MessageBox.show(MobileSalesActivity.this,
										getString(R.string.ErrorLogin));
							}
						});
					}
				}
			}
		};
		thread.start();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (this.notificationReceiver != null)
			C2DMMessaging.removeNotificationReceiver(notificationReceiver);
	}

	public void syncCheck(Settings settings) {
		if (settings != null && settings.isSyncOnStart()) {
			SyncTask task = new SyncTask(this);
			task.execute();
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		// Request Setting
		case Constants.RequestCodes.ChangeSettings:
			if (data != null && data.getExtras() != null) {
				Bundle extra = data.getExtras();
				if (extra.containsKey(Constants.SettingsChanged)) {
					boolean changed = extra
							.getBoolean(Constants.SettingsChanged);
					if (!changed) {
						return;
					}
				}
			}
			setContentView(R.layout.main);
			Settings settings = Settings.getSettings();
			// MobileSalesActivity.this.buildMenu(settings);
			if (settings != null)
				this.syncData();
			break;
		default:
			break;
		}
		Settings settings = Settings.getSettings();
		this.initLanguage(settings);

	}

	private EmployeeAccess login(String serverUrl, String username,
			String password, String c2dmRegId) {
		String url = String.format(UnformatedEndpoints.AuthEndpoint, serverUrl);
		Configuration conf = new Configuration(url);
		AuthServiceClient authService = new AuthServiceClient(conf);
		EmployeeAccess access = null;
		try {
			access = authService.Login(username, password, c2dmRegId);
		} catch (Exception e) {
			Log.e(LogFlags.RestService, "Could not login on server", e);
		}
		return access;
	}

	public void onClick(View v) {
		// TODO Auto-generated method stub
		Intent intent = new Intent(v.getContext(), SettingsActivity.class);
		switch (v.getId()) {
		case R.id.main_products:
			intent = new Intent(v.getContext(), Products.class);
			break;
		case R.id.main_client:
			intent = new Intent(v.getContext(), Clients.class);
			break;
		case R.id.main_tasks:
			intent = new Intent(v.getContext(), Tasks.class);
			break;
		case R.id.main_messages:
			intent = new Intent(v.getContext(), Messages.class);
			break;
		case R.id.main_orders:
			intent = new Intent(v.getContext(), Orders.class);
			break;
		case R.id.main_buttonMore_task:
			intent = new Intent(v.getContext(), ListTask.class);
			intent.putExtra(Constants.SelectedDate, dateToDay);
			break;
		case R.id.main_buttonMore_messages:
			intent = new Intent(v.getContext(), Messages.class);
			break;
		default:
			break;
		}
		startActivityForResult(intent, 0);
	}
}
